package org.lucky.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.lucky.mapper.InviteCodeMapper;
import org.lucky.mapper.InviteMapper;
import org.lucky.mapper.LuckyMapper;
import org.lucky.mapper.UserMapper;
import org.lucky.service.ILuckyService;
import org.lucky_common.domain.*;
import org.lucky_common.util.AjaxResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.Objects;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

@Service
public class LuckyServiceImpl extends ServiceImpl<LuckyMapper, LuckyShare> implements ILuckyService {
    @Resource
    private UserMapper userMapper;

    @Resource
    private LuckyMapper luckyMapper;

    @Resource
    private InviteMapper inviteMapper;

    @Resource
    private InviteCodeMapper inviteCodeMapper;

    @Autowired
    private StringRedisTemplate redisTemplate;

    public String recordValidClick(ParseParamObj parseParamObj) {
        String s = redisTemplate.opsForValue().get("share:" + parseParamObj.getRef());
        System.out.println(s);
        if (Boolean.TRUE.equals(redisTemplate.hasKey("share:" + parseParamObj.getRef()))) {
            LuckyShare inviteCode = luckyMapper.selectOne(new QueryWrapper<LuckyShare>().eq("inviteCode", parseParamObj.getRef()));
            if (inviteCode.getParentId() != null){
                return "void";
            }else {
                if (parseParamObj.getRef2() != null){
                    LuckyShare inviteCode2 = luckyMapper.selectOne(new QueryWrapper<LuckyShare>().eq("inviteCode", parseParamObj.getRef2()));
                    inviteCode2.setParentId(inviteCode.getId());
                    luckyMapper.updateById(inviteCode2);
                }
                inviteCode.setVerifyCount(inviteCode.getVerifyCount()+1);
                luckyMapper.updateById(inviteCode);
                return "effective";
            }
        }else {
            LuckyShare inviteCode = luckyMapper.selectOne(new QueryWrapper<LuckyShare>().eq("inviteCode", parseParamObj.getRef()));
            if (inviteCode != null){
                User id = userMapper.selectOne(new QueryWrapper<User>().eq("id", inviteCode.getUserId()));
                if (id != null){
                    redisTemplate.expire("share:" + parseParamObj.getRef(),30,TimeUnit.MINUTES);
                }
                if (inviteCode.getParentId() != null){
                    return "void";
                }else {
                    if (parseParamObj.getRef2() != null){
                        LuckyShare inviteCode2 = luckyMapper.selectOne(new QueryWrapper<LuckyShare>().eq("inviteCode", parseParamObj.getRef2()));
                        inviteCode2.setParentId(inviteCode.getId());
                        luckyMapper.updateById(inviteCode2);
                    }
                    inviteCode.setVerifyCount(inviteCode.getVerifyCount()+1);
                    luckyMapper.updateById(inviteCode);
                    return "effective";
                }
            }else {
                return "void";
            }
        }
    }

    @Override
    public String verifyShare(ParseParamObj parseParamObj) {
        if (parseParamObj.getRef2() != null){
            if (parseParamObj.getRef().equals(parseParamObj.getRef2())) {
                return "self";
            }
            Boolean aBoolean = redisTemplate.hasKey("share:"+parseParamObj.getRef2());
            if (Boolean.TRUE.equals(aBoolean)){
                LuckyShare inviteCode2 = luckyMapper.selectOne(new QueryWrapper<LuckyShare>().eq("inviteCode", parseParamObj.getRef2()));
                if (inviteCode2.getParentId() !=null ){
                    return "openDialog";
                }else {
                    return "openDialog4";
                }
            }else {
                LuckyShare inviteCode = luckyMapper.selectOne(new QueryWrapper<LuckyShare>().eq("inviteCode", parseParamObj.getRef2()));
                if (inviteCode != null ){
                    User id = userMapper.selectOne(new QueryWrapper<User>().eq("id", inviteCode.getUserId()));
                    if (id != null){
                        redisTemplate.expire("share:"+parseParamObj.getRef2(),30,TimeUnit.MINUTES);
                    }

                    if (inviteCode.getParentId() != null ){
                        return "openDialog";
                    }else {
                        return "openDialog4";
                    }
                }else {
                    return "flush";
                }
            }
        }else {
            if (parseParamObj.getRef() != null){
                Boolean aBoolean = redisTemplate.hasKey("share:"+parseParamObj.getRef());
                LuckyShare inviteCode = luckyMapper.selectOne(new QueryWrapper<LuckyShare>().eq("inviteCode", parseParamObj.getRef()));
                if (Boolean.TRUE.equals(aBoolean) && inviteCode !=null ){
                    return "flush";
                }else {
                    return "valid";
                }
            }else {
                return "valid";
            }
        }
    }

    @Override
    public String addCount(ParseParamObj parseParamObj) {
        if (Boolean.TRUE.equals(redisTemplate.hasKey("share:" + parseParamObj.getRef()))) {
            LuckyShare inviteCode = luckyMapper.selectOne(new QueryWrapper<LuckyShare>().eq("inviteCode", parseParamObj.getRef()));
            inviteCode.setCount(inviteCode.getCount()+1);
            luckyMapper.updateById(inviteCode);
            return "effective";
        }else {
            LuckyShare inviteCode = luckyMapper.selectOne(new QueryWrapper<LuckyShare>().eq("inviteCode", parseParamObj.getRef()));
            if (inviteCode != null){
                User id = userMapper.selectOne(new QueryWrapper<User>().eq("id", inviteCode.getUserId()));
                if (id != null){
                    redisTemplate.expire("share:" + parseParamObj.getRef(),30,TimeUnit.MINUTES);
                }
                inviteCode.setCount(inviteCode.getCount()+1);
                luckyMapper.updateById(inviteCode);
                return "void";
            }else {
                return "valid";
            }
        }
    }

    @Override
    public LuckyShare flushCount(ParseParamObj parseParamObj) {
        Boolean aBoolean = redisTemplate.hasKey("share:"+parseParamObj.getRef());
        LuckyShare inviteCode = luckyMapper.selectOneWithInvite(parseParamObj.getRef());
        if (Boolean.TRUE.equals(aBoolean)) {
            if (inviteCode != null) {
                inviteCode.setVerifyCount(inviteCode.getVerifyCount() == null ? 0 : inviteCode.getVerifyCount());
                inviteCode.setUserId(null);
                System.out.println(inviteCode.getInviteCode());
                return inviteCode;
            }else {
                redisTemplate.delete(parseParamObj.getRef());
                return null;
            }
        }else {
            if (inviteCode != null) {
                redisTemplate.opsForValue().set("share:" + parseParamObj.getRef(),inviteCode.getUserId().toString(),30,TimeUnit.MINUTES);
                inviteCode.setExpire(true);
                return inviteCode;
            }
        }
        return null;
    }

    @Override
    public AjaxResult redirect(ParseParamObj parseParamObj) {
        if (parseParamObj == null){
            return AjaxResult.error("无效链接",2010);
        }else {
            LuckyShare inviteCode = luckyMapper.selectOne(new QueryWrapper<LuckyShare>().eq("inviteCode", parseParamObj.getRef()));
            Boolean aBoolean = redisTemplate.hasKey("share:" + parseParamObj.getRef());
            if (inviteCode != null && Boolean.TRUE.equals(aBoolean)){
                return AjaxResult.success();
            }
        }
        return AjaxResult.error("无效链接",2010);
    }

    @Override
    public LuckyShare updateByCode(ParseParamObj parseParamObj) {
        if (parseParamObj.getRef() != null && parseParamObj.getMi() != null){
            LuckyShare inviteCode = luckyMapper.selectOne(new QueryWrapper<LuckyShare>().eq("inviteCode", parseParamObj.getRef()));
            if (inviteCode != null){
                inviteCode.setInviteCode2(parseParamObj.getMi());
                luckyMapper.updateById(inviteCode);
            }
            return inviteCode;
        }else {
            return null;
        }
    }

    //-------------------------------------------------------------------------------------


    public LuckyShare updateByCode2(ParseParamObj parseParamObj) {
        //如果传过来的值不为空
        if (parseParamObj.getRef() != null && parseParamObj.getMi() != null){
            //先查数据库
            LuckyShare luckyShareByCode = luckyMapper.selectOne(new QueryWrapper<LuckyShare>().eq("inviteCode", parseParamObj.getRef()));
            //判断是第几阶段
            if (luckyShareByCode != null){
                //第二阶段
                InviteCode inviteCode = new InviteCode();
                if (luckyShareByCode.isSubmitParam() && luckyShareByCode.isSecondStage()){
                    inviteCode.setInviteId(luckyShareByCode.getId());
                }else {
                    //第一阶段
                    inviteCode.setLuckyShareId(luckyShareByCode.getId());
                }
                inviteCode.setInviteCode2(parseParamObj.getMi());
                inviteCodeMapper.insert(inviteCode);
                luckyShareByCode.setInviteCode2(inviteCode.getInviteCode2());
            }
            return luckyShareByCode;
        }else {
            return null;
        }
    }

    public String upCount(ParseParamObj parseParamObj) {
        if (parseParamObj != null){
            LuckyShare luckyShare = luckyMapper.selectOneWithInvite(parseParamObj.getRef());
            if (luckyShare != null) {
                luckyShare.setCount(luckyShare.getCount() + 1);
                luckyMapper.updateById(luckyShare);
                return "effective";
            }
        }
        return "valid";
    }

    public String upCount2(ParseParamObj parseParamObj) {
        if (parseParamObj != null){
            InviteParam invitedCode = inviteMapper.selectOne(new QueryWrapper<InviteParam>().eq("invitedCode", parseParamObj.getRef()));
            if (invitedCode != null) {
                invitedCode.setCount2(invitedCode.getCount2() + 1);
                inviteMapper.updateById(invitedCode);
                return "effective";
            }
        }
        return "valid";
    }

    public String recordValidClick2(ParseParamObj parseParamObj) {
        if(parseParamObj == null || parseParamObj.getRef() == null || parseParamObj.getRef2() == null){
            return "null";
        }else {
            if (parseParamObj.getRef().equals(parseParamObj.getRef2())) {
                return "self";
            }
            LuckyShare inviteCode1 = luckyMapper.selectOne(new QueryWrapper<LuckyShare>().eq("inviteCode", parseParamObj.getRef2()));
            LuckyShare inviteCode = luckyMapper.selectOne(new QueryWrapper<LuckyShare>().eq("inviteCode", parseParamObj.getRef()));
            if (inviteCode != null && inviteCode1 != null){
                if (inviteCode.getParentId() == null){
                    //可以助力
                    if (inviteCode.isFirstStage() && inviteCode1.isFirstStage()){
                        return "openFirstStage";
                    }
                    return "openDialog";
                }else {
                    //不可以助力
                    if (Objects.equals(inviteCode.getParentId(), inviteCode1.getId())){
                        return "closeItDialog";
                    }
                    return "closeDialog";
                }
            }else {
                return "null";
            }
        }
    }

    public AjaxResult check(ParseParamObj parseParamObj) {
        if (parseParamObj != null){
            LuckyShare luckyShare = luckyMapper.selectOneWithInvite(parseParamObj.getRef());
            LuckyShare luckyShare1 = luckyMapper.selectOneWithInvite(parseParamObj.getRef2());
            if (luckyShare != null && luckyShare1 != null){
                luckyShare.setParentId(luckyShare1.getId());
                luckyShare1.setVerifyCount(luckyShare1.getVerifyCount() + 1);
                luckyMapper.updateById(luckyShare1);
                luckyMapper.updateById(luckyShare);
                return AjaxResult.success("effective");
            }
        }
        return AjaxResult.error();
    }

    public LuckyShare generateUniqueShareToken(ParseParamObj parseParamObj) {
        LuckyShare luckyShareByCode = luckyMapper.selectOneWithInvite(parseParamObj.getRef());
        InviteParam inviteParamByCode = inviteMapper.selectOne(new QueryWrapper<InviteParam>().eq("invitedCode", parseParamObj.getRef()));
        String uniqueToken = UUID.randomUUID().toString().replaceAll("-","");
        if (luckyShareByCode == null){
            User user = new User(null,"","","","","","",uniqueToken,new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
            userMapper.insert(user);
            LuckyShare luckyShare = new LuckyShare(null, uniqueToken, null, null, null, user.getId(), null, false, false);
            luckyShare.setClickCount(0);
            luckyShare.setData(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
            luckyMapper.insert(luckyShare);
            InviteParam inviteParam = new InviteParam(null, null, null, uniqueToken, null,new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()),0);
            inviteMapper.insert(inviteParam);
            return luckyShare;
        }else {
            luckyShareByCode.setInviteCode(luckyShareByCode.getInviteCode());
            luckyMapper.updateById(luckyShareByCode);
            inviteParamByCode.setInvitedCode(luckyShareByCode.getInviteCode());
            inviteMapper.updateById(inviteParamByCode);
            return luckyShareByCode;
        }
    }

    public LuckyShare flushCount2(ParseParamObj parseParamObj) {
        LuckyShare inviteCode = luckyMapper.selectOneWithInvite(parseParamObj.getRef());
        if (inviteCode != null) {
            inviteCode.setVerifyCount(inviteCode.getVerifyCount() == null ? 0 : inviteCode.getVerifyCount());
            inviteCode.setUserId(null);
            return inviteCode;
        }
        return null;
    }

    public String recordValidClick3(ParseParamObj parseParamObj) {
        //先判断是否为空
        if(parseParamObj == null || parseParamObj.getRef() == null || parseParamObj.getRef2() == null){
            return "null";
        }else {
            LuckyShare luckyShare = luckyMapper.selectOneWithInvite(parseParamObj.getRef());
            LuckyShare luckyShare2 = luckyMapper.selectOneWithInvite(parseParamObj.getRef2());
            //再判断是否符合第二阶段
            if (luckyShare2.isSecondStage() && luckyShare2.isSubmitParam()){
                if (parseParamObj.getRef().equals(parseParamObj.getRef2())) {
                    return "self";
                }

                //判断是否又父Id
                if (luckyShare.getInviteParam().getParentId() == null){
                    //助力成功
                    return "openDialog";
                }else {
                    //不可以助力
                    if (Objects.equals(luckyShare.getInviteParam().getParentId(), luckyShare2.getId())){
                        //不能再帮他
                        return "closeItDialog";
                    }
                    //不能帮别人
                    return "closeDialog";
                }
            }else {
                return "forbidden";
            }
        }
    }

    public AjaxResult check2(ParseParamObj parseParamObj) {
        if (parseParamObj != null){
            InviteParam invitedCode = inviteMapper.selectOne(new QueryWrapper<InviteParam>().eq("invitedCode", parseParamObj.getRef()));
            InviteParam invitedCode2 = inviteMapper.selectOne(new QueryWrapper<InviteParam>().eq("invitedCode", parseParamObj.getRef2()));
            if (invitedCode != null && invitedCode2 != null){
                invitedCode.setParentId(invitedCode2.getId());
                invitedCode2.setEffectiveCount(invitedCode2.getEffectiveCount() + 1);
                inviteMapper.updateById(invitedCode);
                inviteMapper.updateById(invitedCode2);
                return AjaxResult.success("effective");
            }
        }
        return AjaxResult.error();
    }

}
